#include "mainwindow.h"
#include <QTextCursor>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , isHexDisplay_(false)
    , isHexSend_(false)
{
    qDebug() << "初始化MainWindow";
    setWindowTitle("串口调试助手");
    
    createUI();
    setupConnections();
    updatePortsInfo();
    qDebug() << "MainWindow初始化完成";
}

MainWindow::~MainWindow()
{
    qDebug() << "销毁MainWindow";
    if (serialPort_.isOpen()) {
        serialPort_.close();
        qDebug() << "关闭串口";
    }
}

void MainWindow::createUI()
{
    qDebug() << "createUI";
    // 创建中央部件和布局
    QWidget *centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);
    QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget);
    
    // 创建分割器
    QSplitter *splitter = new QSplitter(Qt::Horizontal, centralWidget);
    mainLayout->addWidget(splitter);
    
    // 左侧控件（串口设置和发送区）
    QWidget *leftWidget = new QWidget(splitter);
    QVBoxLayout *leftLayout = new QVBoxLayout(leftWidget);
    
    // 串口设置组
    QGroupBox *serialSettingsGroupBox = new QGroupBox("串口设置", leftWidget);
    QGridLayout *serialSettingsLayout = new QGridLayout(serialSettingsGroupBox);
    
    // 端口设置
    serialSettingsLayout->addWidget(new QLabel("端口："), 0, 0);
    portComboBox_ = new QComboBox(serialSettingsGroupBox);
    serialSettingsLayout->addWidget(portComboBox_, 0, 1);
    refreshPortsButton_ = new QPushButton("刷新", serialSettingsGroupBox);
    serialSettingsLayout->addWidget(refreshPortsButton_, 0, 2);
    
    // 波特率设置
    serialSettingsLayout->addWidget(new QLabel("波特率："), 1, 0);
    baudRateComboBox_ = new QComboBox(serialSettingsGroupBox);
    baudRateComboBox_->addItem("1200", QSerialPort::Baud1200);
    baudRateComboBox_->addItem("2400", QSerialPort::Baud2400);
    baudRateComboBox_->addItem("4800", QSerialPort::Baud4800);
    baudRateComboBox_->addItem("9600", QSerialPort::Baud9600);
    baudRateComboBox_->addItem("19200", QSerialPort::Baud19200);
    baudRateComboBox_->addItem("38400", QSerialPort::Baud38400);
    baudRateComboBox_->addItem("57600", QSerialPort::Baud57600);
    baudRateComboBox_->addItem("115200", QSerialPort::Baud115200);
    baudRateComboBox_->setCurrentIndex(7); // 默认115200
    serialSettingsLayout->addWidget(baudRateComboBox_, 1, 1, 1, 2);
    
    // 数据位设置
    serialSettingsLayout->addWidget(new QLabel("数据位："), 2, 0);
    dataBitsComboBox_ = new QComboBox(serialSettingsGroupBox);
    dataBitsComboBox_->addItem("5", QSerialPort::Data5);
    dataBitsComboBox_->addItem("6", QSerialPort::Data6);
    dataBitsComboBox_->addItem("7", QSerialPort::Data7);
    dataBitsComboBox_->addItem("8", QSerialPort::Data8);
    dataBitsComboBox_->setCurrentIndex(3); // 默认8位
    serialSettingsLayout->addWidget(dataBitsComboBox_, 2, 1, 1, 2);
    
    // 校验位设置
    serialSettingsLayout->addWidget(new QLabel("校验位："), 3, 0);
    parityComboBox_ = new QComboBox(serialSettingsGroupBox);
    parityComboBox_->addItem("无", QSerialPort::NoParity);
    parityComboBox_->addItem("奇校验", QSerialPort::OddParity);
    parityComboBox_->addItem("偶校验", QSerialPort::EvenParity);
    parityComboBox_->addItem("空校验", QSerialPort::SpaceParity);
    parityComboBox_->addItem("标志校验", QSerialPort::MarkParity);
    parityComboBox_->setCurrentIndex(0); // 默认无校验
    serialSettingsLayout->addWidget(parityComboBox_, 3, 1, 1, 2);
    
    // 停止位设置
    serialSettingsLayout->addWidget(new QLabel("停止位："), 4, 0);
    stopBitsComboBox_ = new QComboBox(serialSettingsGroupBox);
    stopBitsComboBox_->addItem("1", QSerialPort::OneStop);
    stopBitsComboBox_->addItem("1.5", QSerialPort::OneAndHalfStop);
    stopBitsComboBox_->addItem("2", QSerialPort::TwoStop);
    stopBitsComboBox_->setCurrentIndex(0); // 默认1位停止位
    serialSettingsLayout->addWidget(stopBitsComboBox_, 4, 1, 1, 2);
    
    // 流控制设置
    serialSettingsLayout->addWidget(new QLabel("流控制："), 5, 0);
    flowControlComboBox_ = new QComboBox(serialSettingsGroupBox);
    flowControlComboBox_->addItem("无", QSerialPort::NoFlowControl);
    flowControlComboBox_->addItem("硬件", QSerialPort::HardwareControl);
    flowControlComboBox_->addItem("软件", QSerialPort::SoftwareControl);
    flowControlComboBox_->setCurrentIndex(0); // 默认无流控制
    serialSettingsLayout->addWidget(flowControlComboBox_, 5, 1, 1, 2);
    
    // 打开/关闭串口按钮
    QHBoxLayout *portButtonsLayout = new QHBoxLayout();
    openPortButton_ = new QPushButton("打开串口", serialSettingsGroupBox);
    closePortButton_ = new QPushButton("关闭串口", serialSettingsGroupBox);
    closePortButton_->setEnabled(false);
    portButtonsLayout->addWidget(openPortButton_);
    portButtonsLayout->addWidget(closePortButton_);
    serialSettingsLayout->addLayout(portButtonsLayout, 6, 0, 1, 3);
    
    leftLayout->addWidget(serialSettingsGroupBox);
    
    // 发送设置组
    QGroupBox *sendSettingsGroupBox = new QGroupBox("发送设置", leftWidget);
    QVBoxLayout *sendSettingsLayout = new QVBoxLayout(sendSettingsGroupBox);
    
    // 发送选项
    QHBoxLayout *sendOptionsLayout = new QHBoxLayout();
    hexSendCheckBox_ = new QCheckBox("十六进制发送", sendSettingsGroupBox);
    autoSendCheckBox_ = new QCheckBox("自动发送", sendSettingsGroupBox);
    autoSendIntervalSpinBox_ = new QSpinBox(sendSettingsGroupBox);
    autoSendIntervalSpinBox_->setRange(10, 10000);
    autoSendIntervalSpinBox_->setValue(1000); // 默认1000ms
    autoSendIntervalSpinBox_->setSuffix(" ms");
    
    sendOptionsLayout->addWidget(hexSendCheckBox_);
    sendOptionsLayout->addWidget(autoSendCheckBox_);
    sendOptionsLayout->addWidget(autoSendIntervalSpinBox_);
    sendSettingsLayout->addLayout(sendOptionsLayout);
    
    // 发送文本框
    sendTextEdit_ = new QTextEdit(sendSettingsGroupBox);
    sendTextEdit_->setMaximumHeight(100);
    sendTextEdit_->setPlaceholderText("在此输入要发送的数据...");
    sendSettingsLayout->addWidget(sendTextEdit_);
    
    // 发送按钮
    QHBoxLayout *sendButtonsLayout = new QHBoxLayout();
    sendButton_ = new QPushButton("发送", sendSettingsGroupBox);
    clearSendButton_ = new QPushButton("清空发送区", sendSettingsGroupBox);
    sendButtonsLayout->addWidget(sendButton_);
    sendButtonsLayout->addWidget(clearSendButton_);
    sendSettingsLayout->addLayout(sendButtonsLayout);
    
    leftLayout->addWidget(sendSettingsGroupBox);
    
    // 右侧控件（接收区）
    QWidget *rightWidget = new QWidget(splitter);
    QVBoxLayout *rightLayout = new QVBoxLayout(rightWidget);
    
    // 接收组
    QGroupBox *receiveGroupBox = new QGroupBox("接收区", rightWidget);
    QVBoxLayout *receiveLayout = new QVBoxLayout(receiveGroupBox);
    
    // 接收选项
    QHBoxLayout *receiveOptionsLayout = new QHBoxLayout();
    hexDisplayCheckBox_ = new QCheckBox("十六进制显示", receiveGroupBox);
    autoScrollCheckBox_ = new QCheckBox("自动滚动", receiveGroupBox);
    autoScrollCheckBox_->setChecked(true);
    clearReceiveButton_ = new QPushButton("清空接收区", receiveGroupBox);
    
    receiveOptionsLayout->addWidget(hexDisplayCheckBox_);
    receiveOptionsLayout->addWidget(autoScrollCheckBox_);
    receiveOptionsLayout->addStretch();
    receiveOptionsLayout->addWidget(clearReceiveButton_);
    receiveLayout->addLayout(receiveOptionsLayout);
    
    // 接收文本框
    receiveTextEdit_ = new QTextEdit(receiveGroupBox);
    receiveTextEdit_->setReadOnly(true);
    receiveLayout->addWidget(receiveTextEdit_);
    
    rightLayout->addWidget(receiveGroupBox);
    
    // 设置分割器初始大小
    splitter->setSizes(QList<int>() << 200 << 400);
    
    // 设置状态栏
    statusBar()->showMessage("就绪");
    
    // 设置窗口大小
    resize(800, 600);
}

void MainWindow::setupConnections()
{
    // 串口操作
    connect(openPortButton_, &QPushButton::clicked, this, &MainWindow::onOpenSerialPort);
    connect(closePortButton_, &QPushButton::clicked, this, &MainWindow::onCloseSerialPort);
    connect(refreshPortsButton_, &QPushButton::clicked, this, &MainWindow::onRefreshPorts);
    
    // 数据发送
    connect(sendButton_, &QPushButton::clicked, this, &MainWindow::onSendData);
    connect(clearSendButton_, &QPushButton::clicked, this, &MainWindow::onClearSendData);
    connect(clearReceiveButton_, &QPushButton::clicked, this, &MainWindow::onClearReceiveData);
    
    // 自动发送
    connect(autoSendCheckBox_, &QCheckBox::toggled, this, &MainWindow::onAutoSendToggled);
    connect(&autoSendTimer_, &QTimer::timeout, this, &MainWindow::onSendData);
    
    // 串口数据接收
    connect(&serialPort_, &QSerialPort::readyRead, this, &MainWindow::onReadData);
    
    // 十六进制显示和发送
    connect(hexDisplayCheckBox_, &QCheckBox::toggled, [this](bool checked) {
        isHexDisplay_ = checked;
    });
    
    connect(hexSendCheckBox_, &QCheckBox::toggled, [this](bool checked) {
        isHexSend_ = checked;
    });
}

void MainWindow::updatePortsInfo()
{
    portComboBox_->clear();
    
    const auto serialPortInfos = QSerialPortInfo::availablePorts();
    qDebug() << "发现" << serialPortInfos.size() << "个串口设备";
    
    for (const QSerialPortInfo &portInfo : serialPortInfos) {
        QString description = portInfo.description();
        QString manufacturer = portInfo.manufacturer();
        QString portName = portInfo.portName();
        
        qDebug() << "串口:" << portName 
                 << "描述:" << description 
                 << "制造商:" << manufacturer;
        
        QString displayText = portName;
        if (!description.isEmpty()) {
            displayText += " - " + description;
        }
        if (!manufacturer.isEmpty()) {
            displayText += " (" + manufacturer + ")";
        }
        
        portComboBox_->addItem(displayText, portName);
    }
}

void MainWindow::onOpenSerialPort()
{
    if (portComboBox_->count() == 0) {
        QMessageBox::warning(this, "警告", "没有可用的串口设备");
        qDebug() << "尝试打开串口失败：没有可用的串口设备";
        return;
    }
    
    QString portName = portComboBox_->currentData().toString();
    int baudRate = baudRateComboBox_->currentData().toInt();
    QSerialPort::DataBits dataBits = static_cast<QSerialPort::DataBits>(dataBitsComboBox_->currentData().toInt());
    QSerialPort::Parity parity = static_cast<QSerialPort::Parity>(parityComboBox_->currentData().toInt());
    QSerialPort::StopBits stopBits = static_cast<QSerialPort::StopBits>(stopBitsComboBox_->currentData().toInt());
    QSerialPort::FlowControl flowControl = static_cast<QSerialPort::FlowControl>(flowControlComboBox_->currentData().toInt());
    
    qDebug() << "尝试打开串口:" << portName 
             << "波特率:" << baudRate 
             << "数据位:" << dataBits 
             << "校验位:" << parity 
             << "停止位:" << stopBits 
             << "流控制:" << flowControl;
    
    serialPort_.setPortName(portName);
    serialPort_.setBaudRate(baudRate);
    serialPort_.setDataBits(dataBits);
    serialPort_.setParity(parity);
    serialPort_.setStopBits(stopBits);
    serialPort_.setFlowControl(flowControl);
    
    if (serialPort_.open(QIODevice::ReadWrite)) {
        qDebug() << "串口打开成功:" << portName;
        openPortButton_->setEnabled(false);
        closePortButton_->setEnabled(true);
        portComboBox_->setEnabled(false);
        baudRateComboBox_->setEnabled(false);
        dataBitsComboBox_->setEnabled(false);
        parityComboBox_->setEnabled(false);
        stopBitsComboBox_->setEnabled(false);
        flowControlComboBox_->setEnabled(false);
        refreshPortsButton_->setEnabled(false);
        
        showStatusMessage(tr("已连接到 %1 : %2, %3, %4, %5, %6")
                         .arg(portComboBox_->currentText())
                         .arg(baudRateComboBox_->currentText())
                         .arg(dataBitsComboBox_->currentText())
                         .arg(parityComboBox_->currentText())
                         .arg(stopBitsComboBox_->currentText())
                         .arg(flowControlComboBox_->currentText()));
    } else {
        QString errorMsg = serialPort_.errorString();
        QMessageBox::critical(this, tr("错误"), tr("无法打开串口: %1\n错误: %2")
                             .arg(portComboBox_->currentText())
                             .arg(errorMsg));
        qDebug() << "串口打开失败:" << portName << "错误:" << errorMsg;
        showStatusMessage(tr("打开串口失败"));
    }
}

void MainWindow::onCloseSerialPort()
{
    if (serialPort_.isOpen()) {
        qDebug() << "关闭串口:" << serialPort_.portName();
        serialPort_.close();
    }
    
    openPortButton_->setEnabled(true);
    closePortButton_->setEnabled(false);
    portComboBox_->setEnabled(true);
    baudRateComboBox_->setEnabled(true);
    dataBitsComboBox_->setEnabled(true);
    parityComboBox_->setEnabled(true);
    stopBitsComboBox_->setEnabled(true);
    flowControlComboBox_->setEnabled(true);
    refreshPortsButton_->setEnabled(true);
    
    // 如果自动发送开启，则关闭
    if (autoSendCheckBox_->isChecked()) {
        qDebug() << "关闭自动发送";
        autoSendCheckBox_->setChecked(false);
    }
    
    showStatusMessage(tr("串口已关闭"));
}

void MainWindow::onSendData()
{
    if (!serialPort_.isOpen()) {
        QMessageBox::warning(this, tr("警告"), tr("请先打开串口"));
        qDebug() << "发送数据失败：串口未打开";
        return;
    }
    
    QString text = sendTextEdit_->toPlainText();
    if (text.isEmpty()) {
        qDebug() << "发送数据为空，取消发送";
        return;
    }
    
    QByteArray data;
    if (isHexSend_) {
        // 处理十六进制发送
        text = text.simplified();
        text.replace(" ", "");
        
        if (text.length() % 2 != 0) {
            QMessageBox::warning(this, tr("警告"), tr("十六进制数据长度必须为偶数"));
            qDebug() << "十六进制数据长度错误:" << text.length();
            return;
        }
        
        bool ok;
        for (int i = 0; i < text.length(); i += 2) {
            QString byteStr = text.mid(i, 2);
            char byte = static_cast<char>(byteStr.toInt(&ok, 16));
            if (!ok) {
                QMessageBox::warning(this, tr("警告"), tr("无效的十六进制数据"));
                qDebug() << "无效的十六进制数据:" << byteStr;
                return;
            }
            data.append(byte);
        }
        qDebug() << "发送十六进制数据，长度:" << data.size() << "字节";
    } else {
        // 处理ASCII发送
        data = text.toUtf8();
        qDebug() << "发送ASCII数据，长度:" << data.size() << "字节";
    }
    
    qint64 bytesWritten = serialPort_.write(data);
    qDebug() << "实际发送:" << bytesWritten << "字节";
    
    // 显示发送时间
    QString currentTime = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
    QString logText = QString("[%1] 发送: %2\n").arg(currentTime).arg(text);
    receiveTextEdit_->append(logText);
}

void MainWindow::onReadData()
{
    QByteArray data = serialPort_.readAll();
    if (data.isEmpty()) {
        return;
    }
    
    qDebug() << "接收数据，长度:" << data.size() << "字节";
    
    // 显示接收时间
    QString currentTime = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
    QString prefix = QString("[%1] 接收: ").arg(currentTime);
    
    if (isHexDisplay_) {
        // 十六进制显示
        QString hexString;
        for (char byte : data) {
            hexString += QString("%1 ").arg(static_cast<quint8>(byte), 2, 16, QLatin1Char('0')).toUpper();
        }
        appendToReceiveText(prefix + hexString, true);
    } else {
        // ASCII显示
        appendToReceiveText(prefix + QString::fromUtf8(data));
    }
}

void MainWindow::onRefreshPorts()
{
    qDebug() << "刷新串口列表";
    updatePortsInfo();
    showStatusMessage(tr("串口列表已刷新"));
}

void MainWindow::onClearReceiveData()
{
    receiveTextEdit_->clear();
    showStatusMessage(tr("接收区已清空"));
}

void MainWindow::onClearSendData()
{
    sendTextEdit_->clear();
    showStatusMessage(tr("发送区已清空"));
}

void MainWindow::onAutoSendToggled(bool checked)
{
    if (checked) {
        if (!serialPort_.isOpen()) {
            QMessageBox::warning(this, tr("警告"), tr("请先打开串口"));
            qDebug() << "自动发送启动失败：串口未打开";
            autoSendCheckBox_->setChecked(false);
            return;
        }
        
        int interval = autoSendIntervalSpinBox_->value();
        qDebug() << "启动自动发送，间隔:" << interval << "毫秒";
        autoSendTimer_.start(interval);
        showStatusMessage(tr("自动发送已启动，间隔: %1 ms").arg(interval));
    } else {
        qDebug() << "停止自动发送";
        autoSendTimer_.stop();
        showStatusMessage(tr("自动发送已停止"));
    }
}

void MainWindow::showStatusMessage(const QString &message)
{
    statusBar()->showMessage(message);
}

void MainWindow::appendToReceiveText(const QString &text, bool isHex)
{
    receiveTextEdit_->append(text);
    
    // 如果启用了自动滚动，则滚动到底部
    if (autoScrollCheckBox_->isChecked()) {
        QTextCursor cursor = receiveTextEdit_->textCursor();
        cursor.movePosition(QTextCursor::End);
        receiveTextEdit_->setTextCursor(cursor);
    }
}

